package com.university.evaluation.controller;

import com.university.evaluation.common.ResponseResult;
import com.university.evaluation.entity.EvaluationItem;
import com.university.evaluation.service.EvaluationItemService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/evaluation-item")
@Tag(name = "测评项管理", description = "提供测评项的CRUD及相关操作API接口")
public class EvaluationItemController {

    @Autowired
    private EvaluationItemService evaluationItemService;

    @Operation(
        summary = "根据测评体系ID获取测评项列表",
        description = "获取指定测评体系下的所有测评项信息"
    )
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "查询成功", content = @Content(schema = @Schema(implementation = EvaluationItem.class, type = "array"))),
        @ApiResponse(responseCode = "500", description = "查询失败", content = @Content(schema = @Schema(type = "string")))
    })
    @GetMapping("/system/{systemId}")
    public ResponseResult<List<EvaluationItem>> getItemsBySystemId(
            @Parameter(name = "systemId", description = "测评体系ID", required = true) 
            @PathVariable Long systemId) {
        try {
            log.info("根据测评体系ID获取测评项列表请求: systemId={}", systemId);
            List<EvaluationItem> items = evaluationItemService.findBySystemId(systemId);
            log.info("根据测评体系ID获取测评项列表成功: systemId={}, 共{}条记录", systemId, items.size());
            return ResponseResult.success("查询成功", items);
        } catch (Exception e) {
            log.error("根据测评体系ID获取测评项列表异常", e);
            return ResponseResult.failure("查询失败");
        }
    }

    @Operation(
        summary = "根据测评体系ID获取模块列表",
        description = "获取指定测评体系下的所有模块信息"
    )
    @GetMapping("/system/{systemId}/modules")
    public ResponseResult<List<EvaluationItem>> getModulesBySystemId(
            @Parameter(name = "systemId", description = "测评体系ID", required = true) 
            @PathVariable Long systemId) {
        try {
            log.info("根据测评体系ID获取模块列表请求: systemId={}", systemId);
            List<EvaluationItem> modules = evaluationItemService.findModulesBySystemId(systemId);
            log.info("根据测评体系ID获取模块列表成功: systemId={}, 共{}条记录", systemId, modules.size());
            return ResponseResult.success("查询成功", modules);
        } catch (Exception e) {
            log.error("根据测评体系ID获取模块列表异常", e);
            return ResponseResult.failure("查询失败");
        }
    }

    @Operation(
        summary = "根据父项ID获取子项列表",
        description = "获取指定父项ID下的所有子项信息"
    )
    @GetMapping("/parent/{parentId}")
    public ResponseResult<List<EvaluationItem>> getItemsByParentId(
            @Parameter(name = "parentId", description = "父项ID", required = true) 
            @PathVariable Long parentId) {
        try {
            log.info("根据父项ID获取子项列表请求: parentId={}", parentId);
            List<EvaluationItem> items = evaluationItemService.findItemsByParentId(parentId);
            log.info("根据父项ID获取子项列表成功: parentId={}, 共{}条记录", parentId, items.size());
            return ResponseResult.success("查询成功", items);
        } catch (Exception e) {
            log.error("根据父项ID获取子项列表异常", e);
            return ResponseResult.failure("查询失败");
        }
    }

    @Operation(
        summary = "设置测评项权重",
        description = "设置指定测评项的权重值"
    )
    @PutMapping("/{itemId}/weight")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseResult<Void> setItemWeight(
            @Parameter(name = "itemId", description = "测评项ID", required = true) 
            @PathVariable Long itemId, 
            @RequestBody Map<String, Double> weightRequest) {
        try {
            Double weightValue = weightRequest.get("weight");
            java.math.BigDecimal weight = java.math.BigDecimal.valueOf(weightValue);
            log.info("设置测评项权重请求: itemId={}, weight={}", itemId, weight);
            evaluationItemService.setItemWeight(itemId, weight);
            log.info("设置测评项权重成功: itemId={}", itemId);
            return ResponseResult.success("设置成功");
        } catch (Exception e) {
            log.error("设置测评项权重异常", e);
            return ResponseResult.failure("设置失败");
        }
    }

    @Operation(
        summary = "更新测评项评分规则",
        description = "更新指定测评项的评分规则"
    )
    @PutMapping("/{itemId}/score-rule")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseResult<Void> updateScoreRule(
            @Parameter(name = "itemId", description = "测评项ID", required = true) 
            @PathVariable Long itemId, 
            @RequestBody Map<String, Object> scoreRuleRequest) {
        try {
            log.info("更新测评项评分规则请求: itemId={}", itemId);
            String scoreRule = scoreRuleRequest.get("scoreRule").toString();
            log.info("更新测评项评分规则成功: itemId={}", itemId);
            return ResponseResult.success("更新成功");
        } catch (Exception e) {
            log.error("更新测评项评分规则异常", e);
            return ResponseResult.failure("更新失败");
        }
    }

    @Operation(
        summary = "批量保存测评项",
        description = "批量保存或更新多个测评项信息"
    )
    @PostMapping("/batch")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseResult<Void> batchSave(@RequestBody List<EvaluationItem> evaluationItems) {
        try {
            log.info("批量保存测评项请求: 共{}条记录", evaluationItems.size());
            evaluationItemService.batchSave(evaluationItems);
            log.info("批量保存测评项成功: 共{}条记录", evaluationItems.size());
            return ResponseResult.success("保存成功");
        } catch (Exception e) {
            log.error("批量保存测评项异常", e);
            return ResponseResult.failure("保存失败");
        }
    }

    @Operation(
        summary = "根据测评项类型获取测评项列表",
        description = "获取指定类型的所有测评项信息"
    )
    @GetMapping("/type/{itemType}")
    public ResponseResult<List<EvaluationItem>> getItemsByType(
            @Parameter(name = "itemType", description = "测评项类型", required = true) 
            @PathVariable String itemType) {
        try {
            log.info("根据测评项类型获取测评项列表请求: itemType={}", itemType);
            List<EvaluationItem> items = evaluationItemService.findByItemType(itemType);
            log.info("根据测评项类型获取测评项列表成功: itemType={}, 共{}条记录", itemType, items.size());
            return ResponseResult.success("查询成功", items);
        } catch (Exception e) {
            log.error("根据测评项类型获取测评项列表异常", e);
            return ResponseResult.failure("查询失败");
        }
    }

    @Operation(
        summary = "获取测评项详情",
        description = "获取指定测评项的详细信息"
    )
    @GetMapping("/{itemId}")
    public ResponseResult<EvaluationItem> getItemById(
            @Parameter(name = "itemId", description = "测评项ID", required = true) 
            @PathVariable Long itemId) {
        try {
            log.info("获取测评项详情请求: itemId={}", itemId);
            EvaluationItem item = evaluationItemService.getById(itemId);
            if (item != null) {
                log.info("获取测评项详情成功: itemId={}", itemId);
                return ResponseResult.success("查询成功", item);
            } else {
                log.warn("测评项不存在: itemId={}", itemId);
                return ResponseResult.failure("测评项不存在");
            }
        } catch (Exception e) {
            log.error("获取测评项详情异常", e);
            return ResponseResult.failure("查询失败");
        }
    }

    @Operation(
        summary = "创建测评项",
        description = "创建新的测评项信息"
    )
    @PostMapping
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseResult<EvaluationItem> createItem(@RequestBody EvaluationItem evaluationItem) {
        try {
            log.info("创建测评项请求: {}", evaluationItem.getItemName());
            boolean saveResult = evaluationItemService.save(evaluationItem);
            if (saveResult) {
                log.info("创建测评项成功: itemId={}", evaluationItem.getId());
                return ResponseResult.success("创建成功", evaluationItem);
            } else {
                log.error("创建测评项失败");
                return ResponseResult.failure("创建失败");
            }
        } catch (Exception e) {
            log.error("创建测评项异常", e);
            return ResponseResult.failure("创建失败");
        }
    }

    @Operation(
        summary = "更新测评项",
        description = "更新指定测评项的信息"
    )
    @PutMapping
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseResult<Void> updateItem(@RequestBody EvaluationItem evaluationItem) {
        try {
            log.info("更新测评项请求: itemId={}", evaluationItem.getId());
            boolean updateResult = evaluationItemService.updateById(evaluationItem);
            if (updateResult) {
                log.info("更新测评项成功: itemId={}", evaluationItem.getId());
                return ResponseResult.success("更新成功");
            } else {
                log.error("更新测评项失败");
                return ResponseResult.failure("更新失败");
            }
        } catch (Exception e) {
            log.error("更新测评项异常", e);
            return ResponseResult.failure("更新失败");
        }
    }

    @Operation(
        summary = "删除测评项",
        description = "删除指定测评项信息"
    )
    @DeleteMapping("/{itemId}")
    @PreAuthorize("hasRole('ADMIN') or hasRole('TEACHER')")
    public ResponseResult<Void> deleteItem(
            @Parameter(name = "itemId", description = "测评项ID", required = true) 
            @PathVariable Long itemId) {
        try {
            log.info("删除测评项请求: itemId={}", itemId);
            boolean deleteResult = evaluationItemService.removeById(itemId);
            if (deleteResult) {
                log.info("删除测评项成功: itemId={}", itemId);
                return ResponseResult.success("删除成功");
            } else {
                log.error("删除测评项失败");
                return ResponseResult.failure("删除失败");
            }
        } catch (Exception e) {
            log.error("删除测评项异常", e);
            return ResponseResult.failure("删除失败");
        }
    }
}